﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;

namespace InterPC.SPF {

    public class DNSProxy : Heijden.DNS.Resolver, InterPC.SPF.IDNSProxy {

        #region Constructors

        /// <summary>
        /// Constructor with no arguments. Use machine default DNS servers
        /// </summary>
        /// <param name="DnsServer">DNS server to use</param>
        public DNSProxy():base() {}

        /// <summary>
        /// Constructor using DNS servers specified.
        /// </summary>
        /// <param name="DnsServers">Set of DNS servers</param>
        public DNSProxy(IPEndPoint[] dnsServers) : base(dnsServers) { }

		/// <summary>
		/// Constructor using DNS server specified.
		/// </summary>
		/// <param name="DnsServer">DNS server to use</param>
        public DNSProxy(IPEndPoint dnsServer) : base(new IPEndPoint[] { dnsServer }) { }

		/// <summary>
		/// Constructor using DNS server and port specified.
		/// </summary>
		/// <param name="ServerIpAddress">DNS server to use</param>
		/// <param name="ServerPortNumber">DNS port to use</param>
        public DNSProxy(IPAddress serverIpAddress, int serverPortNumber) : base(new IPEndPoint(serverIpAddress, serverPortNumber)) { }

		/// <summary>
		/// Constructor using DNS address and port specified.
		/// </summary>
		/// <param name="ServerIpAddress">DNS server address to use</param>
		/// <param name="ServerPortNumber">DNS port to use</param>
        public DNSProxy(string serverIpAddress, int serverPortNumber) : base(IPAddress.Parse(serverIpAddress), serverPortNumber) { }
		
		/// <summary>
		/// Constructor using DNS address.
		/// </summary>
		/// <param name="ServerIpAddress">DNS server address to use</param>
        public DNSProxy(string serverIpAddress) : base(IPAddress.Parse(serverIpAddress), Heijden.DNS.Resolver.DefaultPort) { }


        #endregion
        
        public string[] GetTXT(string domain) {
            return this.LookupTXT(domain);
        }

        public string[] GetSPF(string domain) {
            return this.LookupSPF(domain);
        }

        public IPAddress[] GetA(string domain) {
            return this.LookupA(domain);
        }

        public IPAddress[] GetAAAA(string domain) {
            return this.LookupAAAA(domain);
        }

        public string[] GetPTR(IPAddress ip) {
            return this.LookupPTR(ip);
        }

        public InterPC.SPF.MXRecord[] GetMX(string domain) {
            return
                (from rec in this.LookupMX(domain)
                 select new InterPC.SPF.MXRecord() { Exchange = rec.Exchange, Preference = rec.Preference }
                ).ToArray();
        }

        public object Lookup(string domain, ushort recordType) {
            switch ((Heijden.DNS.Type)recordType) {
                case Heijden.DNS.Type.A:
                    return GetA(domain);
                case Heijden.DNS.Type.AAAA:
                    return GetAAAA(domain);
                case Heijden.DNS.Type.TXT:
                    return GetTXT(domain);
                case Heijden.DNS.Type.SPF:
                    return GetSPF(domain);
                case Heijden.DNS.Type.MX:
                    return GetMX(domain);
                default:
                    throw new NotSupportedException();
            }
        }

    }

}
